#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <minigui/common.h>
#include <minigui/minigui.h>
#include <minigui/gdi.h>
#include <minigui/window.h>
#include <minigui/control.h>
#include "resource.h"
#include "func.h"
#include "lang.h"
#include "com.h"
#include "mhlabel.h"
#include "mhbtn.h"
#include "belt.h"
#include "sys.h"


/*
 *
 */
static void CreateBeltInterface(HWND hWnd)
{
    char sc[64] = {0};
    CreateWindow (MH_STATIC_NAME,
        "",
        WS_CHILD | WS_VISIBLE,
        ID_ESC,
        CX_TIME_BMP - CX_ASK_BMP - 10,
        8,
        CX_ASK_BMP,
        CY_ASK_BMP,
        hWnd, (int)&g_bmp[BMP_FALSE]);
    CreateWindow(MH_LABEL_NAME,
        MW_LEFT_CAPTION,
        WS_CHILD | WS_VISIBLE | BS_LEFT,
        IDC_STATIC,
        CX_EDGE_LEFT,
        60,
        100,
        20,
        hWnd, MH_LABEL_BKGND_BLACK | MH_LABEL_TEXT_GREEN);
    sprintf(sc, "%d", GetMacLeftCom(g_knit_data));
    CreateWindow(MH_BTN_NAME,
        sc,
        WS_CHILD | WS_VISIBLE | BS_LEFT | BS_FLAT,
        ID_LEFT,
        CX_EDGE_LEFT + 110,
        60,
        80,
        20,
        hWnd, MH_BTN_BKGND_BLACK | MH_BTN_TEXT_CYAN);
    CreateWindow(MH_LABEL_NAME,
        MW_RGHT_CAPTION,
        WS_CHILD | WS_VISIBLE | BS_LEFT,
        IDC_STATIC,
        CX_EDGE_LEFT,
        90,
        100,
        20,
        hWnd, MH_LABEL_BKGND_BLACK | MH_LABEL_TEXT_GREEN);
    sprintf(sc, "%d", GetMacRightCom(g_knit_data));
    CreateWindow(MH_BTN_NAME,
        sc,
        WS_CHILD | WS_VISIBLE | BS_LEFT | BS_FLAT,
        ID_RGHT,
        CX_EDGE_LEFT + 110,
        90,
        80,
        20,
        hWnd, MH_BTN_BKGND_BLACK | MH_BTN_TEXT_CYAN);
    CreateWindow(MH_LABEL_NAME,
        MW_BELT_CX_CAPTION,
        WS_CHILD | WS_VISIBLE | BS_LEFT,
        IDC_STATIC,
        CX_EDGE_LEFT,
        120,
        100,
        20,
        hWnd, MH_LABEL_BKGND_BLACK | MH_LABEL_TEXT_GREEN);
    sprintf(sc, "%d", GetBeltPitchAdj(g_knit_data));
    CreateWindow(MH_BTN_NAME,
        sc,
        WS_CHILD | WS_VISIBLE | BS_LEFT | BS_FLAT,
        IDC_INTER,
        CX_EDGE_LEFT + 110,
        120,
        80,
        20,
        hWnd, MH_BTN_BKGND_BLACK | MH_BTN_TEXT_CYAN);
    CreateWindow(MH_LABEL_NAME,
        "CODER:",
        WS_CHILD | WS_VISIBLE | BS_LEFT,
        IDC_STATIC,
        CX_EDGE_LEFT,
        150,
        100,
        20,
        hWnd, MH_LABEL_BKGND_BLACK | MH_LABEL_TEXT_GREEN);
    CreateWindow(MH_LABEL_NAME,
        "179760",
        WS_CHILD | WS_VISIBLE | BS_LEFT,
        ID_BELT,
        CX_EDGE_LEFT + 110,
        150,
        80,
        20,
        hWnd, MH_LABEL_BKGND_BLACK | MH_LABEL_TEXT_CYAN);
}
/*
 *
 */
static void OnBtnCmd(HWND hWnd, ushort nID)
{
    WND_EXTRA_DATA data;
    data.value = GetWindowAdditionalData(hWnd);
    switch(nID)
    {
    case ID_ESC:
        {
            if(data.pwnd_sys)
            {
                if(data.pwnd_sys->sys_query_state)
                {
                    data.pwnd_sys->sys_query_state = FALSE;
                    pthread_join(data.pwnd_sys->sys_thread_id, NULL);
                }
                if(data.pwnd_sys->change.sys)
                {
                    FlushSysWndBelt(GetHosting(hWnd));
                }
            }
            PostMessage(hWnd, MSG_CLOSE, 0, 0);
        }
        break;
    case ID_LEFT:
        {
            const char *sc = GetWindowCaption(GetDlgItem(hWnd, ID_BELT));
            if(sc)
            {
                HWND hWndTmp = GetDlgItem(hWnd, nID);
                SetWindowCaption(hWndTmp, sc);
                InvalidateRect(hWndTmp, NULL, TRUE);
                SetMacLeftCom(g_knit_data, atoi(sc));
                data.pwnd_sys->change.sys = TRUE;
            }
        }
        break;
    case ID_RGHT:
        {
            const char *sc = GetWindowCaption(GetDlgItem(hWnd, ID_BELT));
            if(sc)
            {
                HWND hWndTmp = GetDlgItem(hWnd, nID);
                SetWindowCaption(hWndTmp, sc);
                InvalidateRect(hWndTmp, NULL, TRUE);
                SetMacRightCom(g_knit_data, atoi(sc));
                data.pwnd_sys->change.sys = TRUE;
            }
        }
        break;
    case IDC_INTER:
        {
            int r = GetMacRightCom(g_knit_data);
            int l = GetMacLeftCom(g_knit_data);
            SetBeltPitchAdj(g_knit_data, r - l);
            char sc[64] = {0};
            sprintf(sc, "%d", r - l);
            HWND hWndTmp = GetDlgItem(hWnd, nID);
            SetWindowCaption(hWndTmp, sc);
            InvalidateRect(hWndTmp, NULL, TRUE);
            data.pwnd_sys->change.sys = TRUE;
        }
        break;
    }
}
/*
 *
 */
static void OnKeyDown(HWND hWnd, uint key)
{
    switch(key)
    {
    case SCANCODE_ESCAPE:
        OnBtnCmd(hWnd, ID_ESC);
        break;
    case SCANCODE_ENTER:
        OnBtnCmd(hWnd, ID_ESC);
        break;
    case SCANCODE_1:
        OnBtnCmd(hWnd, ID_LEFT);
        break;
    case SCANCODE_2:
        OnBtnCmd(hWnd, ID_RGHT);
        break;
    case SCANCODE_3:
        OnBtnCmd(hWnd, IDC_INTER);
        break;
    case SCANCODE_CURSORBLOCKLEFT:
        {
            WND_EXTRA_DATA data;
            data.value = GetWindowAdditionalData(hWnd);
            if(data.pwnd_sys)
            {
                if(data.pwnd_sys->change.left)
                {
                    data.pwnd_sys->change.left = FALSE;
                    RunMotor(g_knit_data, 0);
                }
                else
                {
                    data.pwnd_sys->change.left = TRUE;
                    data.pwnd_sys->change.right = FALSE;
                    RunMotor(g_knit_data, -10);
                }
            }
        }
        break;
    case SCANCODE_CURSORBLOCKRIGHT:
        {
            WND_EXTRA_DATA data;
            data.value = GetWindowAdditionalData(hWnd);
            if(data.pwnd_sys)
            {
                if(data.pwnd_sys->change.right)
                {
                    data.pwnd_sys->change.right = FALSE;
                    RunMotor(g_knit_data, 0);
                }
                else
                {
                    data.pwnd_sys->change.right = TRUE;
                    data.pwnd_sys->change.left = FALSE;
                    RunMotor(g_knit_data, 10);
                }
            }
        }
        break;
    }
}
/*
 * update needle from machine
 */
static void *UpdateCurrentPulse(void *arg)
{
    HWND hWnd = (HWND)arg;
    WND_SYS *p = (WND_SYS *)GetWindowAdditionalData(hWnd);
    int ret = 0;
    int needle = 0;
    while(p->sys_query_state)
    {
        if(1)
        {
            ret = GetCurrentPulse(g_knit_data, &needle);
            if(!ret)
            {
                HWND hWndTmp = GetDlgItem(hWnd, ID_BELT);
                int n = atoi(GetWindowCaption(hWndTmp));
                if(n != needle)
                {
                    char sc[32] = {0};
                    sprintf(sc, "%d", needle);
                    SetWindowCaption(hWndTmp, sc);
                    InvalidateRect(hWndTmp, NULL, TRUE);
                }
            }
            usleep(20000);
        }
        else
        {
            usleep(50000);
        }
    }
    pthread_exit(0);
}
/*
 *
 */
static int BeltProc(HWND hWnd, int message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
    case MSG_CREATE:
        {
            CreateBeltInterface(hWnd);
        }
        break;
    case MSG_PAINT:
        {
            WND_SYS *p = (WND_SYS *) GetWindowAdditionalData(hWnd);
            if(p)
            {
                if(!p->sys_query_state)
                {
                    p->sys_query_state = TRUE;
                    if(pthread_create(&p->sys_thread_id, NULL, (void*) UpdateCurrentPulse, (void*) hWnd))
                    {
                        printf("failed to create system param thread\n");
                        p->sys_query_state = FALSE;
                    }
                }
            }
            HDC hdc = GetClientDC(hWnd);
            RECT rect;
            GetClientRect(hWnd, &rect);
            rect.top += MASTER_TITLE_TOP;
            rect.bottom = rect.top + MASTER_TITLE_HEIGHT - 1;
            SetBkMode(hdc, BM_TRANSPARENT);
            SetTextColor(hdc, COLOR_HQ_GREEN(hdc));
            DrawText(hdc, GetWindowCaption (hWnd), -1, &rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
            ReleaseDC(hdc);
        }
        break;
    case MSG_CLOSE:
        {
            HWND hHosting = GetHosting(hWnd);
            if(hHosting != HWND_INVALID)
            {
                EnableWindow(hHosting, TRUE);
                int n = GetBeltPitchAdj(g_knit_data);
                if(n)
                {
                    n = GetTotalNeedle(g_knit_data) * GetMacLeftCom(g_knit_data) / n;
                    if(n != GetNeedleZero(g_knit_data))
                    {
                        SetNeedleZero(g_knit_data, n);
                        HWND hWndTmp = GetDlgItem(hHosting, IDC_EDIT_NEEDLE_ZERO);
                        if(hWndTmp != HWND_INVALID)
                        {
                            char sc[32] = {0};
                            sprintf(sc, "%d", n);
                            SetWindowCaption(hWndTmp, sc);
                        }
                    }
                }
            }
            DestroyMainWindow(hWnd);
            MainWindowCleanup(hWnd);
        }
        return 0;
    case MSG_DESTROY:
        {
            ShowWindow(hWnd, SW_HIDE);
            DestroyAllControls (hWnd);
            WND_SYS *p = (WND_SYS *)GetWindowAdditionalData(hWnd);
            if(p)
            {
                free(p);
                SetWindowAdditionalData(hWnd, 0);
            }
        }
        break;
    case MSG_KEYDOWN:
        {
            OnKeyDown(hWnd, wParam);
        }
        return 0;
    case MSG_ERASEBKGND:
        {
            DrawBitmapBkGnd(hWnd, (RECT*)lParam, &g_bmp[BMP_TIME]);
        }
        return 0;
    case MSG_COMMAND:
        {
            OnBtnCmd(hWnd, LOWORD(wParam));
        }
        return 0;
    }
    return DefaultMainWinProc(hWnd, message, wParam, lParam);
}
/*
 *
 */
HWND CreateBeltWindow(HWND hHosting)
{
    int x = (CX_SCREEN - CX_TIME_BMP) / 2;
    int y = (CY_SCREEN - CY_TIME_BMP) / 2;
    MAINWINCREATE CreateInfo;
    CreateInfo.dwStyle = WS_VISIBLE;
    CreateInfo.dwExStyle = WS_EX_NONE;
    CreateInfo.spCaption = MW_BELT_INTER_CAPTION;
    CreateInfo.hMenu = 0;
    CreateInfo.hCursor = GetSystemCursor(0);
    CreateInfo.hIcon = 0;
    CreateInfo.MainWindowProc = BeltProc;
    CreateInfo.lx = x;
    CreateInfo.ty = y;
    CreateInfo.rx = x + CX_TIME_BMP;
    CreateInfo.by = y + CY_TIME_BMP;
    CreateInfo.iBkColor = COLOR_lightwhite;
    CreateInfo.dwAddData = (int)calloc(1, sizeof(WND_SYS));
    CreateInfo.hHosting = hHosting;
    HWND hWnd = CreateMainWindow(&CreateInfo);
    if(hWnd != HWND_INVALID)
    {
        EnableWindow(hHosting, FALSE);
        ShowWindow(hWnd, SW_SHOWNORMAL);
    }
    return hWnd;
}

